<template>
  <div class="ssal-calendar-container">
    <div class="day-view">
      <div class="day-header" ref="headerHeight">
        <div class="header-time-zone">{{ timeZone }}</div>
        <div class="single-day-container">
          <div
            class="day-header-title"
            @click.prevent="handleDayHeaderLeft"
            @contextmenu.prevent="handleDayHeaderRight"
          >
            <div
              :class="[
                'day-title',
                nowDate.fullDate ==
                currentTime.year +
                  '-' +
                  currentTime.month +
                  '-' +
                  currentTime.day
                  ? 'isToday'
                  : '',
              ]"
              v-if="nowDate.date"
            >
              <div class="day">{{ nowDate.date }}</div>
              <div class="day-other">
                {{ nowDate.month }}月,{{ nowDate.lunar.ncWeek }}
              </div>
              <div class="day-lunar">
                {{ nowDate.lunar.IMonthCn + nowDate.lunar.IDayCn
                }}<template v-if="nowDate.lunar.Term"
                  >（{{ nowDate.lunar.Term }}）</template
                >
              </div>
            </div>
          </div>
          <div
            v-if="showHeaderTime"
            class="time-placeholder-box"
            style="position: relative; top: 40px; height: 20px"
          >
            <div class="close-bg" @click="showHeaderTime = false"></div>
            <div
              class="time-placeholder"
              :style="{ top: 0, left: 0, width: '100%', marginLeft: 0 }"
              id="timeRef"
              data-view="day"
              data-header="header"
            >
              添加事件
            </div>
          </div>
          <AllDayEventItem
            v-if="deEvents.allDayArr.length > 0 && nowDate"
            :event="deEvents.allDayArr"
            :date="nowDate.fullDate"
            @getEvent="getDayEvent"
          >
            <template v-slot:default="slotItem">
              {{ slotItem.title }}, {{ slotItem.actionStartTime }} ~
              {{ slotItem.actionEndTime }}
            </template>
          </AllDayEventItem>
        </div>
      </div>
      <div class="day-container">
        <ScrollBar
          autoHide
          :forData="len"
          :ScrollTop="ScrollTop"
          :listenScrollBottom="listenScrollBottom"
          :listenScrollTop="listenScrollTop"
          :listenScroll="listenScroll"
        >
          <div
            class="scroll-container"
            id="scroll"
            @dragenter="handledrapEnter($event)"
            @dragover="handledrapOver($event)"
          >
            <div
              v-if="
                currentTime &&
                nowDate.fullDate ==
                  currentTime.year +
                    '-' +
                    currentTime.month +
                    '-' +
                    currentTime.day &&
                checkBig
              "
              class="time-line"
              :style="{ top: getTop + 'px' }"
            >
              <div class="current">
                {{ currentTime.hour + ":" + currentTime.min }}
              </div>
              <div
                class="current-line firstDayDotted"
                style="width: calc(100% - 80px)"
              ></div>
            </div>
            <div class="time-container">
              <div
                class="time-cell"
                v-for="(item, index) in initHours"
                :key="item"
              >
                <div :class="['time', checkOut(item) ? '' : 'outTime']">
                  {{ index == 0 ? "" : item }}
                </div>
                <div class="day-cell">
                  <div
                    class="day-half"
                    v-for="(half, index) in 2"
                    :key="half"
                    :data-date="nowDate.fullDate"
                    :data-index="index"
                    :data-time="filterHalfTime(item, index)"
                    @click="handleDayLeft"
                    @contextmenu.prevent="handleDayRight"
                    @dragenter="handledrapEnter($event)"
                    @dragleave="handledragLevel($event)"
                    @dragover="handledrapOver($event)"
                    @drop="handledragLevel($event)"
                  ></div>
                </div>
              </div>
            </div>
            <div v-if="showTime" class="time-placeholder-box">
              <div class="close-bg" @click="showTime = false"></div>
              <div
                class="time-placeholder timeRef"
                :style="{
                  top: timeDistance.top * 40 + 'px',
                  left: 0,
                  width: 'calc(100% - 80px)',
                }"
                id="timeRef"
                data-type="scroll"
                data-view="day"
              >
                {{ selectedTime }}
              </div>
            </div>
            <EventItem
              v-if="
                initHours.length > 0 &&
                deEvents.sameDayArr.length > 0 &&
                week &&
                nowDate
              "
              view="day"
              :events="deEvents.sameDayArr"
              :hours="initHours"
              :week="week"
              :date="nowDate.fullDate"
              :dropData="dropMessage"
              @getEvent="getEvent"
              @exchangeDate="exchangeDate"
            >
              <template v-slot:week="slotItem">
                {{ slotItem.title || "（无主题）" }}, {{ slotItem.hours }}
              </template>
            </EventItem>
            <EventForm
              :dialogEventFormVisible="dialogEventFormVisible"
              :default-form="defaultForm"
              :belongsUser="belongsUser"
              @get-form="getForm"
              @close-form="CloseForm"
            ></EventForm>
            <model-option-box
              :dialogModelVisible="dialogModelVisible"
              @close-form="CloseModel"
              @get-quick="getQuick"
            ></model-option-box>
          </div>
        </ScrollBar>
      </div>
    </div>
    <EventDetail
      :dialogEventDetailVisible="dialogEventDetailVisible"
      :event="itemInfo"
      @edit-info="editInfo"
      @del-event="delEvent"
    ></EventDetail>
  </div>
</template>

<script>
import ScrollBar from "../ScrollBar/index.vue";
import EventItem from "../EventItem/index.vue";
import AllDayEventItem from "../AllDayEventItem/index.vue";
import EventDetail from "../EventDetail/index.vue";
import EventForm from "../EventForm/index.vue";
import ModelOptionBox from "../ModelOptionBox/index.vue";
import {
  ref,
  toRefs,
  reactive,
  onMounted,
  watch,
  onBeforeUnmount,
  computed,
  nextTick,
} from "vue";
import { getCurrent, getTimeZone } from "../lib/utils";
import { filterDay } from "../lib/event";
export default {
  name: "DayPage",
  components: {
    ScrollBar,
    EventItem,
    AllDayEventItem,
    EventDetail,
    EventForm,
    ModelOptionBox,
  },
  props: {
    events: {
      type: Array,
      default() {
        return [];
      },
    },
    nowDate: {
      type: Object,
      default() {
        return {};
      },
    },
    initHours: {
      type: Array,
      default() {
        return [];
      },
    },
    week: {
      type: Array,
      default() {
        return [];
      },
    },
    belongsUser: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  computed: {
    filterHalfTime() {
      return (item, index) => {
        if (index == 1) {
          return item.split(":")[0] + ":30";
        } else {
          return item;
        }
      };
    },
  },
  setup(props, context) {
    let { events, nowDate, initHours } = toRefs(props);
    let calcHours = ref(initHours.value);
    let scrollDistance = ref(0); // 滚动距离
    let timeDistance = ref({
      top: 0,
      left: 0,
    });
    const showHeaderTime = ref(false);
    const showTime = ref(false);
    let selectedTime = ref(null); // 展示的时间
    let dialogEventDetailVisible = ref(false); // 事件详情
    let dialogEventFormVisible = ref(false); // 事件表单
    let ScrollTop = ref(0);
    let itemInfo = ref({}); // 事件信息
    let headerHeight = ref(0); // header的高度
    let defaultForm = ref({}); // 默认表单
    let deEvents = ref(filterDay(events.value)); // 筛选后的events
    let currentTime = ref({});
    let dialogModelVisible = ref(false);
    let dropMessage = ref({});
    let num = 0;
    const state = reactive({
      timeZone: `GMT${getTimeZone()}`,
      len: 0,
      currentInterver: null,
    });
    // 滚动条事件
    const listenScrollBottom = () => {};
    const listenScrollTop = () => {};
    const listenScroll = (e) => {
      scrollDistance.value = e;
    };
    // 右鍵天
    const handleDayRight = (e) => {
      dialogModelVisible.value = !dialogModelVisible.value;
      getDistance(e);
    };
    // 左键天
    const handleDayLeft = (e) => {
      num++;
      setTimeout(() => {
        if (num == 1) {
          const { fullDate, spliceTime } = getDistance(e);
          defaultForm.value["actionStartTime"] =
            fullDate + " " + spliceTime.split(" - ")[0];
          if (spliceTime.split(" - ")[1] == "00:00") {
            const nextDay = new Date(
              new Date(fullDate + " 00:00:00").getTime() + 24 * 60 * 60 * 1000
            );
            const nextDate =
              nextDay.getFullYear() +
              "-" +
              (nextDay.getMonth() + 1 < 10
                ? "0" + (nextDay.getMonth() + 1)
                : nextDay.getMonth() + 1) +
              "-" +
              (nextDay.getDate() < 10
                ? "0" + nextDay.getDate()
                : nextDay.getDate());
            defaultForm.value["actionEndTime"] =
              nextDate + " " + spliceTime.split(" - ")[1];
          } else {
            defaultForm.value["actionEndTime"] =
              fullDate + " " + spliceTime.split(" - ")[1];
          }
          defaultForm.value["isAllDay"] = false;
          dialogEventFormVisible.value = !dialogEventFormVisible.value;
        }
        if (num == 2) {
          console.log("双击");
        }
        if (num > 2) {
          num = 0;
        }
        num = 0;
      }, 250);
    };
    // 左键天的header
    const handleDayHeaderLeft = () => {
      getDayHeaderDistance();
      const { fullDate } = currentTime.value;
      defaultForm.value["actionStartTime"] = fullDate + " 00:00";
      defaultForm.value["actionEndTime"] = fullDate + " 23:59";
      defaultForm.value["isAllDay"] = true;
      dialogEventFormVisible.value = !dialogEventFormVisible.value;
    };
    // 右键天的header
    const handleDayHeaderRight = () => {
      dialogModelVisible.value = !dialogModelVisible.value;
      getDayHeaderDistance();
    };
    // 关闭model
    const CloseModel = () => {
      showHeaderTime.value = false;
      showTime.value = false;
    };
    // 获取天的header距离
    const getDayHeaderDistance = () => {
      showHeaderTime.value = true;
    };
    const getEvent = (e) => {
      const id = e.target.dataset.id;
      const info = events.value.find((item) => {
        return item.id == id;
      });
      itemInfo.value = {
        info,
        ele: e,
        scroll: scrollDistance.value,
        headerHeight: headerHeight.value.offsetHeight,
      };
      dialogEventDetailVisible.value = !dialogEventDetailVisible.value;
    };
    // allday of day
    const getDayEvent = (e) => {
      const id = e.target.dataset.id;
      const info = events.value.find((item) => {
        return item.id == id;
      });
      itemInfo.value = {
        info,
        ele: e,
        type: "day",
      };
      dialogEventDetailVisible.value = !dialogEventDetailVisible.value;
    };
    // 获取当前的时间距离
    const getDistance = (e) => {
      const { time, index } = e.target.dataset;
      // 0:当前时间到半小时后, 1:当前时间半小时后到下一个小时; ex: [00:00 - 00:30], [00:30 - 01:00]
      let spliceTime = time.split(":")[0];
      // 根据时间设置时间格子的top, left;
      let top = 0;
      top = spliceTime - calcHours.value[0].split(":00")[0];
      if (index == 0) {
        spliceTime = spliceTime + ":00" + " - " + spliceTime + ":30";
      } else {
        top += 0.5;
        if (spliceTime == 23) {
          spliceTime = spliceTime + ":30 - 00:00";
        } else {
          let nextHour = spliceTime - 0 + 1;
          if (nextHour < 10) nextHour = "0" + nextHour;
          spliceTime = spliceTime + ":30" + " - " + nextHour + ":00";
        }
      }
      showTime.value = true;
      timeDistance.value.top = top;
      selectedTime.value = spliceTime;
      if (e.target.dataset.date) {
        const { fullDate, day, date } = e.target.dataset;
        timeDistance.value.left = day;
        return {
          fullDate: fullDate || date,
          spliceTime,
        };
      } else {
        return {
          fullDate: nowDate.value.fullDate,
          spliceTime,
        };
      }
    };
    // 关闭Form
    const CloseForm = () => {
      showHeaderTime.value = false;
      showTime.value = false;
      defaultForm.value = {};
    };
    // 获取form
    const getForm = (e) => {
      context.emit('submitForm', e)
      // deEvents.value = filterDay(events.value);
    };
    // 编辑form
    const editInfo = (e) => {
      const { event } = e;
      defaultForm.value = event;
      dialogEventFormVisible.value = !dialogEventFormVisible.value;
    };
    // 删除form
    const delEvent = (e) => {
      context.emit('delEvent', e)
      dialogEventDetailVisible.value = !dialogEventDetailVisible.value;
      // deEvents.value = filterDay(events.value);
    };
    const getLeft = (e) => {
      itemInfo.value = e.form;
      dialogEventFormVisible.value = e.dialogEventFormVisible;
    };
    // 设置时间线距顶点的高度
    const getTop = computed(() => {
      return getCurrentTop();
    });
    // 获取当前时间距离开始的距离
    const getCurrentTop = () => {
      const currentPercent = currentTime.value.min / 60;
      if (calcHours.value.length > 0) {
        return (
          (currentTime.value.hour -
            calcHours.value[0].split(":")[0] +
            currentPercent) *
            40 -
          10
        );
      } else {
        return (currentTime.value.hour - 0 + currentPercent) * 40 - 10;
      }
    };
    // 判断当前时间是否小于时间轴的最后一个时间
    const checkBig = computed(() => {
      const current = currentTime.value.hour;
      const len = calcHours.value.length;
      const last = len > 0 ? calcHours.value[len - 1].split(":")[0] : -1;
      if (current <= last) {
        return true;
      } else {
        return false;
      }
    });
    // 判断时间
    const checkOut = computed(() => {
      return (item) => {
        item = item.split(":00")[0];
        const current =
          currentTime.value.year +
          "-" +
          currentTime.value.month +
          "-" +
          currentTime.value.day;
        return (
          current !== nowDate.value.fullDate || item > currentTime.value.hour
        );
      };
    });
    // 快捷操作
    // eslint-disable-next-line no-unused-vars
    const getQuick = (e) => {
      // console.log(e)
    };
    const handledrapEnter = (e) => {
      e.preventDefault();
      e.dataTransfer.dropEffect = "move";
    };
    const handledrapOver = (e) => {
      e.preventDefault();
      e.dataTransfer.dropEffect = "move";
    };
    const handledragLevel = (e) => {
      dropMessage.value = e.target.dataset;
    };
    const exchangeDate = e => {
      context.emit('exchangeDate', e)
    }
    watch(
      () => initHours.value,
      (newVal, oldVal) => {
        calcHours.value = newVal || oldVal;
      }
    );
    watch(
      () => events.value,
      (newVal, oldVal) => {
        const val = newVal || oldVal
        deEvents.value = filterDay(val);
      },
      {
        deep: true
      }
    )
    onMounted(() => {
      currentTime.value = getCurrent();
      state.currentInterver = setInterval(() => {
        currentTime.value = getCurrent();
      }, 1000);
      if(currentTime && nowDate.fullDate == currentTime.value.year + '-' + currentTime.value.month + '-' + currentTime.value.day && checkBig){
        nextTick(() => {
          const currentTimeRelease =
            ((currentTime.value.hour * 60 + Number(currentTime.value.min)) * 2) /
              3 -
            ((calcHours.value[0].split(":")[0] * 60 * 2) / 3 +
              calcHours.value[0].split(":")[1]);
          const scrollHeight =
            document.querySelectorAll("#scroll")[0].scrollHeight;
          const clientHeight =
            document.querySelectorAll(".content-wrapper")[0].clientHeight;
          const pixel = clientHeight / scrollHeight;
          ScrollTop.value = currentTimeRelease * pixel;
        });
      }
    });
    onBeforeUnmount(() => {
      clearInterval(state.currentInterver);
    });
    return {
      ...state,
      listenScrollBottom,
      listenScrollTop,
      listenScroll,
      scrollDistance,
      timeDistance,
      getEvent,
      getDayEvent,
      // 点击事件
      handleDayLeft,
      handleDayRight,
      handleDayHeaderLeft,
      handleDayHeaderRight,
      CloseForm,
      getForm,
      editInfo,
      delEvent,
      getLeft,
      ScrollTop,
      currentTime,
      showTime,
      showHeaderTime,
      // 展示事件
      dialogEventDetailVisible,
      dialogEventFormVisible,
      itemInfo,
      headerHeight,
      defaultForm,
      deEvents,
      getTop,
      checkBig,
      checkOut,
      selectedTime,
      dialogModelVisible,
      CloseModel,
      getQuick,
      handledrapEnter,
      handledrapOver,
      handledragLevel,
      dropMessage,
      exchangeDate
    };
  },
};
</script>

<style scoped lang="scss">
.ssal-calendar-container {
  height: calc(100% - 41px);
  border: 1px solid #e4e7ed;
  position: relative;
  box-sizing: border-box;
  .scroll-container {
    position: relative;
  }
  .day-view {
    height: 100%;
    min-height: 500px;
    position: relative;
    display: flex;
    flex-direction: column;
    .day-header {
      display: flex;
      align-items: stretch;
      box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
      min-height: 40px;
      .single-day-container {
        flex: 1;
        position: relative;
        min-height: 40px;
      }
      .day-title {
        display: flex;
        align-items: center;
        padding-left: 10px;
        height: 40px;
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        .day {
          font-size: 18px;
          margin-right: 10px;
          color: #303133;
          width: 25px;
          height: 25px;
          display: flex;
          align-items: center;
          justify-content: center;
          font-weight: bold;
        }
        .day-other {
          font-size: 12px;
          color: #606266;
          margin-right: 10px;
        }
        .day-lunar {
          font-size: 12px;
          color: #909399;
        }
      }
      .isToday {
        .day {
          color: #fff;
          background: var(--ss-color-primary);
          border-radius: 50%;
          font-size: 14px;
        }
        .day-other {
          color: var(--ss-color-primary);
        }
      }
    }
    .day-container {
      flex: auto;
      overflow: auto;
      overflow-y: scroll;
      position: relative;
      margin-bottom: 1px;
      margin-right: -7px;
    }
  }
  .time-line {
    position: absolute;
    z-index: 399;
    width: 100%;
    display: flex;
    align-items: center;
    height: 1px;
    .current {
      font-size: 13px;
      color: #f56c6c;
      background: #fff;
      width: 78px;
      text-align: center;
      position: relative;
      top: 8px;
      left: 1px;
    }
    .current-line {
      border-top: 1px solid #f56c6c;
      position: relative;
      top: 8px;
    }
    .firstDayDotted::before {
      content: "";
      position: absolute;
      top: -4px;
      left: -4px;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background: #f56c6c;
    }
    .current-dotted {
      position: absolute;
      top: 4px;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background: #f56c6c;
    }
  }
  .time-placeholder {
    position: absolute;
    z-index: 999;
    margin-left: 80px;
    background: #ecf5ff;
    border: 1px dashed var(--ss-color-primary);
    font-size: 12px;
    text-align: center;
    color: var(--ss-color-primary);
    height: 20px;
    line-height: 20px;
    box-sizing: border-box;
  }
  .close-bg {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 998;
    background: rgba(0, 0, 0, 0.2);
  }
  .time-cell {
    display: flex;
    align-items: stretch;
    height: 40px;
    .time {
      width: 80px;
      height: 100%;
      font-size: 12px;
      color: #606266;
      border-right: 1px solid #e4e7ed;
      box-sizing: border-box;
      display: flex;
      align-items: flex-start;
      justify-content: center;
      position: relative;
      top: -10px;
    }
    &:last-child {
      .week-data,
      .day-cell,
      .month-view .month-date {
        border-bottom: none;
      }
      .time{
        &::after {
          content: "";
          position: absolute;
          border-right: 1px solid #e4e7ed;
          right: -1px;
          height: 10px;
          bottom: -9px;
        }
      }
    }
    .outTime {
      color: #c0c4cc;
    }
    .day-cell {
      box-sizing: border-box;
      border-bottom: 1px solid #e4e7ed;
      width: calc(100% - 80px);
      .day-half {
        height: 50%;
      }
    }
  }
  .header-time-zone {
    width: 80px;
    border-right: 1px solid #e4e7ed;
    text-align: center;
    font-size: 13px;
    color: #606266;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 10px 10px 5px 10px;
  }
}
</style>